<template>
  <!-- 可选提示 -->
  <div v-if="showTips" class="keyboard-control-tips">WASD 移动，↑↓←→ 旋转视角，Q/E 或 PageUp/PageDown 上下移动，Shift 加速，R 重置视角</div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, reactive, watch } from 'vue';
import { SuperMap3D } from '@/utils/supermap3d';

const { __viewer } = window;
const viewer = __viewer;

const props = defineProps<{
  showTips?: boolean;
  enabled: boolean; // 必传，是否启用键盘控制
}>();

const showTips = ref(props.showTips);
watch(
  () => props.showTips,
  (newVal) => {
    showTips.value = newVal;
  },
);
console.log('showTips', showTips);

// 本地控制启用状态
const enabled = ref(props.enabled);

// 监听外部传入的 enabled 变化
watch(
  () => props.enabled,
  (newVal) => {
    enabled.value = newVal;
  },
);

// 控制标志位
const flags = reactive({
  moveForward: false,
  moveBackward: false,
  moveLeft: false,
  moveRight: false,
  moveUp: false,
  moveDown: false,

  accelerating: false, //Shift

  rotateLeft: false,
  rotateRight: false,
  rotateUp: false,
  rotateDown: false,
});

// 临时变量复用
const moveScratch = new SuperMap3D.Cartesian3();
const directionScratch = new SuperMap3D.Cartesian3();

// 键码映射
function getFlagForKeyCode(keyCode: number): keyof typeof flags | 'resetView' | undefined {
  switch (keyCode) {
    case 87:
      return 'moveForward'; // W
    case 83:
      return 'moveBackward'; // S
    case 65:
      return 'moveLeft'; // A
    case 68:
      return 'moveRight'; // D
    case 16:
      return 'accelerating'; // Shift

    case 37:
      return 'rotateLeft'; // ←
    case 39:
      return 'rotateRight'; // →
    case 38:
      return 'rotateUp'; // ↑
    case 40:
      return 'rotateDown'; // ↓

    case 33:
      return 'moveUp'; // PageUp
    case 81:
      return 'moveUp'; // Q

    case 82:
      return 'resetView'; // R

    case 34:
      return 'moveDown'; // PageDown
    case 69:
      return 'moveDown'; // E
    default:
      return undefined;
  }
}

// 重置视角
function resetView() {
  if (!viewer) return;
  const camera = viewer.camera;
  camera.setView({
    destination: SuperMap3D.Cartesian3.fromDegrees(116.456809, 39.895055, 1500),
    orientation: {
      heading: 0,
      pitch: -Math.PI / 4,
      roll: 0,
    },
  });
}

// 方向计算（前进方向需考虑地形切线）
function computeDirection(preDirection: any, cameraPosition: any) {
  const tangentPlane = new SuperMap3D.EllipsoidTangentPlane(cameraPosition);
  SuperMap3D.Cartesian3.multiplyByScalar(preDirection, 0.1, moveScratch);
  SuperMap3D.Cartesian3.add(cameraPosition, moveScratch, moveScratch);
  const projectPoint2D = tangentPlane.projectPointOntoPlane(moveScratch);
  const projectPoint3D = tangentPlane.projectPointOntoEllipsoid(projectPoint2D);
  const origin2D = tangentPlane.projectPointOntoPlane(cameraPosition);
  const origin3D = tangentPlane.projectPointOntoEllipsoid(origin2D);
  const direction = SuperMap3D.Cartesian3.subtract(projectPoint3D, origin3D, directionScratch);
  SuperMap3D.Cartesian3.normalize(direction, direction);
  return direction;
}

// 键盘事件监听
function onKeyDown(e: KeyboardEvent) {
  if (!enabled.value) return;
  const flag = getFlagForKeyCode(e.keyCode);
  if (flag === 'resetView') {
    e.preventDefault();
    resetView();
    return;
  }
  if (flag) {
    e.preventDefault();
    flags[flag] = true;
  }
}

function onKeyUp(e: KeyboardEvent) {
  if (!enabled.value) return;
  const flag = getFlagForKeyCode(e.keyCode);
  if (flag && flag !== 'resetView') {
    flags[flag] = false;
  }
}

// 每帧相机移动
function onTick() {
  if (!enabled.value || !viewer) return;
  const camera = viewer.camera;
  const ellipsoid = viewer.scene.globe.ellipsoid;
  const position = camera.position;
  const height = ellipsoid.cartesianToCartographic(position).height;
  // const moveRate = height / 100.0;

  let moveRate = Math.min(Math.max(height / 100, 0.5), 20);
  if (flags.accelerating) moveRate *= 5;

  //空间移动
  if (flags.moveForward) {
    const dir = computeDirection(camera.direction, position);
    camera.move(dir, moveRate);
  }
  if (flags.moveBackward) {
    const dir = computeDirection(camera.direction, position);
    camera.move(dir, -moveRate);
  }
  if (flags.moveLeft) camera.moveLeft(moveRate);
  if (flags.moveRight) camera.moveRight(moveRate);
  if (flags.moveUp) camera.moveUp(moveRate);
  if (flags.moveDown) camera.moveDown(moveRate);

  // 视角旋转（单位角度）
  const rotateStep = 0.005;
  if (flags.rotateLeft) camera.lookLeft(rotateStep);
  if (flags.rotateRight) camera.lookRight(rotateStep);
  if (flags.rotateUp) camera.lookUp(rotateStep);
  if (flags.rotateDown) camera.lookDown(rotateStep);
}

// 初始化键盘控制
onMounted(() => {
  const canvas = viewer.scene.canvas;
  canvas.tabIndex = 0;
  canvas.focus();

  document.addEventListener('keydown', onKeyDown);
  document.addEventListener('keyup', onKeyUp);
  viewer.clock.onTick.addEventListener(onTick);
});

// 清理事件
onUnmounted(() => {
  document.removeEventListener('keydown', onKeyDown);
  document.removeEventListener('keyup', onKeyUp);
  viewer.clock.onTick.removeEventListener(onTick);
});
// };
</script>

<style scoped>
.keyboard-control-tips {
  position: absolute;
  top: 10px;
  left: 10px;
  background: rgba(0, 0, 0, 0.65);
  color: white;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
  z-index: 999;
}
</style>
